package com.thinkit.bigdata.web.service.impl.audioSearch;

import com.google.common.base.Strings;
import com.thinkit.bigdata.core.ConfigHelper;
import com.thinkit.bigdata.core.util.DateFormatUtil;
import com.thinkit.bigdata.core.util.TaskUtil;
import com.thinkit.bigdata.core.util.es.ESUtil;
import com.thinkit.bigdata.core.util.excel.XlsUtil;
import com.thinkit.bigdata.web.controller.pubmet.PubMethod;
import com.thinkit.bigdata.web.coremet.SystemStatic;
import com.thinkit.bigdata.web.model.BaseEntity;
import com.thinkit.bigdata.web.model.es.audioEs.BusinessTags;
import com.thinkit.bigdata.web.model.es.audioEs.VoiceInfoDto;
import com.thinkit.bigdata.web.model.result.HtmlResult;
import com.thinkit.bigdata.web.service.audioSearch.AudioSearchPubMet;
import org.apache.log4j.Logger;
import org.apache.lucene.search.join.ScoreMode;
import org.apache.poi.hssf.usermodel.*;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Service
public class AudioSearchPubMetImpl implements AudioSearchPubMet {

    private static Logger logger = Logger.getLogger(AudioSearchPubMetImpl.class);

    @Resource
    private ESUtil esUtil;

    @Override
    public Map<String, List<String>> strFormatJson(String provinceCode, String citys) {
        Map<String, List<String>> json = new HashMap<>();
        json.put(provinceCode, new ArrayList<>());
        if (!Strings.isNullOrEmpty(citys)) {
            json.put(provinceCode, Arrays.asList(citys.split(",")));
        }
        return json;
    }

    @Override
    public BoolQueryBuilder getQuery(String logTxt, Map<String, String[]> request, HttpServletRequest req) {
        String provinceCode = "";//省份
        if (request.get("provinceCode") != null && !request.get("provinceCode")[0].equals("")) {
            provinceCode = request.get("provinceCode")[0];
        }
        String customerlocs = "";//归属地
        if (request.get("customerloc") != null && !request.get("customerloc")[0].equals("")) {
            customerlocs = request.get("customerloc")[0];
        }
        String callDirection = "";//呼叫类型
        if (request.get("callDirection")!= null && !request.get("callDirection").equals("")) {
            callDirection = request.get("callDirection")[0];
        }
        String serialNumber = "";//录音流水
        if (request.get("serialNumber")!= null && !request.get("serialNumber").equals("")) {
            serialNumber = request.get("serialNumber")[0];
        }
        String seatGroup = "";//坐席班组
        if (request.get("seatGroup")!= null && !request.get("seatGroup").equals("")) {
            seatGroup = request.get("seatGroup")[0];
        }
        String seatId = "";//坐席工号
        if (request.get("seatId")!= null && !request.get("seatId").equals("")) {
            seatId = request.get("seatId")[0];
        }
        String seatName = "";//坐席工号
        if (request.get("seatName")!= null && !request.get("seatName").equals("")) {
            seatName = request.get("seatName")[0];
        }
        String proPhoneNum = "";//受理号码
        if (request.get("proPhoneNum")!= null && !request.get("proPhoneNum").equals("")) {
            proPhoneNum = request.get("proPhoneNum")[0];
        }
        String customerNumber = "";//客户号码
        if (request.get("customerNumber")!= null && !request.get("customerNumber").equals("")) {
            customerNumber = request.get("customerNumber")[0];
        }
        String customerLevels = "";//客户星级f
        if (request.get("customerLevel")!= null && !request.get("customerLevel").equals("")) {
            customerLevels = request.get("customerLevel")[0];
        }
        String customerSign = "";//重要客户
        if (request.get("customerSign")!= null && !request.get("customerSign").equals("")) {
            customerSign = request.get("customerSign")[0];
        }
        String onHooks = "";//挂机方
        if (request.get("onHook")!= null && !request.get("onHook").equals("")) {
            onHooks = request.get("onHook")[0];
        }
        String callStartTime = "";//通话开始时间
        if (request.get("callStartTime")!= null && !request.get("callStartTime").equals("")) {
            callStartTime = request.get("callStartTime")[0];
        }
        String callEndTime = "";//通话结束时间
        if (request.get("callEndTime")!= null && !request.get("callEndTime").equals("")) {
            callEndTime = request.get("callEndTime")[0];
        }
        String holdDurationMin = "";//通话时长小值
        if (request.get("holdDurationMin")!= null && !request.get("holdDurationMin").equals("")) {
            holdDurationMin = request.get("holdDurationMin")[0];
        }
        String holdDurationMax = "";//通话时长大值
        if (request.get("holdDurationMax")!= null && !request.get("holdDurationMax").equals("")) {
            holdDurationMax = request.get("holdDurationMax")[0];
        }
        String reCallFlag = "";//重复来电
        if (request.get("reCallFlag")!= null && !request.get("reCallFlag").equals("")) {
            reCallFlag = request.get("reCallFlag")[0];
        }
        String satisfactions = "";//满意度
        if (request.get("satisfaction")!= null && !request.get("satisfaction").equals("")) {
            satisfactions = request.get("satisfaction")[0];
        }
        String proStatus = "";//录音流水
        if (request.get("proStatus")!= null && !request.get("proStatus").equals("")) {
            proStatus = request.get("proStatus")[0];
        }
        String inputTimeBegin = "";//入库时间
        if (request.get("inputTimeBegin")!= null && !request.get("inputTimeBegin").equals("")) {
            inputTimeBegin = request.get("inputTimeBegin")[0];
        }
        String inputTimeEnd = "";//入库时间
        if (request.get("inputTimeEnd")!= null && !request.get("inputTimeEnd").equals("")) {
            inputTimeEnd = request.get("inputTimeEnd")[0];
        }
        String sysTagFlags = "";//系统打标标识
        if (request.get("sysTagFlag")!= null && !request.get("sysTagFlag").equals("")) {
            sysTagFlags = request.get("sysTagFlag")[0];
        }
        String appealFlags = "";//业务场景标识
        if (request.get("appealFlag")!= null && !request.get("appealFlag").equals("")) {
            appealFlags = request.get("appealFlag")[0];
        }
        String tagUse = "";//打标方 系统打标量(sysTag)  人工打标量(addTag)  人工纠正量(corTag)
        if (request.get("tagUse")!= null && !request.get("tagUse").equals("")) {
            tagUse = request.get("tagUse")[0];
        }
        String sysTagIds = "";//系统标签_标签ids
        String sysTagAll = "";//系统标签全部
        if (request.get("sysTagIds")!= null && !request.get("sysTagIds").equals("")) {
            sysTagIds = request.get("sysTagIds")[0];
            if ("全部".equals(sysTagIds)) sysTagAll = sysTagIds;
            if ("全部".equals(sysTagIds)) sysTagIds = "";

        }
        String sysOperator = "";//系统标签_运算符  //should  ||   must
        if (request.get("sysOperator")!= null && !request.get("sysOperator").equals("")) {
            sysOperator = request.get("sysOperator")[0];
        }
        String telTagIds = "";//话务小结_标签ids
        String telTagAll = "";//话务小结全部
        if (request.get("telTagIds")!= null && !request.get("telTagIds").equals("")) {
            telTagIds = request.get("telTagIds")[0];
            if ("全部".equals(telTagIds)) telTagAll = telTagIds;
            if ("全部".equals(telTagIds)) telTagIds = "";
        }
        String telOperator = "";//话务小结_运算符  //should  ||   must
        if (request.get("telOperator")!= null && !request.get("telOperator").equals("")) {
            telOperator = request.get("telOperator")[0];
        }
        String scenes = "";//场景  -  多个
        if (request.get("scenes")!= null && !request.get("scenes").equals("")) {
            scenes = request.get("scenes")[0];
        }
        logger.info(logTxt + "provinceCode = " + provinceCode);
        logger.info(logTxt + "customerlocs = " + customerlocs);
        logger.info(logTxt + "callDirection = " + callDirection);
        logger.info(logTxt + "serialNumber = " + serialNumber);
        logger.info(logTxt + "seatGroup = " + seatGroup);
        logger.info(logTxt + "seatId = " + seatId);
        logger.info(logTxt + "seatName = " + seatName);
        logger.info(logTxt + "proPhoneNum = " + proPhoneNum);
        logger.info(logTxt + "customerNumber = " + customerNumber);
        logger.info(logTxt + "customerLevel = " + customerLevels);
        logger.info(logTxt + "customerSign = " + customerSign);
        logger.info(logTxt + "onHooks = " + onHooks);
        logger.info(logTxt + "callStartTime = " + callStartTime);
        logger.info(logTxt + "callEndTime = " + callEndTime);
        logger.info(logTxt + "holdDurationMin = " + holdDurationMin);
        logger.info(logTxt + "holdDurationMax = " + holdDurationMax);
        logger.info(logTxt + "reCallFlag = " + reCallFlag);
        logger.info(logTxt + "satisfactions = " + satisfactions);
        logger.info(logTxt + "proStatus = " + proStatus);
        logger.info(logTxt + "inputTimeBegin = " + inputTimeBegin);
        logger.info(logTxt + "inputTimeEnd = " + inputTimeEnd);
        logger.info(logTxt + "sysTagFlags = " + sysTagFlags);
        logger.info(logTxt + "appealFlags = " + appealFlags);
        logger.info(logTxt + "tagUse = " + tagUse);
        logger.info(logTxt + "sysTagIds = " + sysTagIds);
        logger.info(logTxt + "sysOperator = " + sysOperator);
        logger.info(logTxt + "telTagIds = " + telTagIds);
        logger.info(logTxt + "telOperator = " + telOperator);
        logger.info(logTxt + "scenes = " + scenes);
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //数据权限
        esUtil.formatQ(boolQuery, seatId);
        if (!Strings.isNullOrEmpty(serialNumber)) {
            boolQuery.must(QueryBuilders.wildcardQuery("serialNumber", "*" + serialNumber + "*"));
        }
        //省份
        if (!Strings.isNullOrEmpty(provinceCode)) {
            PubMethod.formatPro(provinceCode, boolQuery);
        }
        if (!Strings.isNullOrEmpty(customerlocs)) {
            PubMethod.formatPC(boolQuery, Arrays.asList(customerlocs.split(",")));
        }
        if (!Strings.isNullOrEmpty(callDirection)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.callDirection", callDirection));
        }
        //挂机方
        if (!Strings.isNullOrEmpty(onHooks)) {
            PubMethod.formatOnHook(boolQuery, Arrays.asList(onHooks.split(",")));
        }
        if (!Strings.isNullOrEmpty(customerNumber)) {
            boolQuery.must(QueryBuilders.wildcardQuery("voiceInfo.customerNum", "*" + customerNumber + "*"));
        }
        if (!Strings.isNullOrEmpty(reCallFlag)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.reCallFlag", reCallFlag));
        }
        if (!Strings.isNullOrEmpty(proPhoneNum)) {
            boolQuery.must(QueryBuilders.wildcardQuery("voiceInfo.proPhoneNum", "*" + proPhoneNum + "*"));
        }
        //客户星级
        if (!Strings.isNullOrEmpty(customerLevels)) {
            PubMethod.formatCustomerLevel(boolQuery, Arrays.asList(customerLevels.split(",")));
        }
        if (!Strings.isNullOrEmpty(customerSign)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.customerSign", customerSign));
        }
        //满意度
        if (!Strings.isNullOrEmpty(satisfactions)) {
            PubMethod.formatSatisfactions(boolQuery, Arrays.asList(satisfactions.split(",")));
        }
        if (!Strings.isNullOrEmpty(seatName)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.seatName", seatName));
        }
        if (!Strings.isNullOrEmpty(seatGroup)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.groupId", seatGroup));
        }
        if (!Strings.isNullOrEmpty(callStartTime)) {
            PubMethod.formatTime(boolQuery, callStartTime, callEndTime);
        }
        if (!Strings.isNullOrEmpty(inputTimeBegin)) {
            boolQuery.must(QueryBuilders.rangeQuery("voiceInfo.inputTime").gte(inputTimeBegin));
        }
        if (!Strings.isNullOrEmpty(inputTimeEnd)) {
            boolQuery.must(QueryBuilders.rangeQuery("voiceInfo.inputTime").lte(inputTimeEnd));
        }
        if (!Strings.isNullOrEmpty(holdDurationMin)) {
            boolQuery.must(QueryBuilders.rangeQuery("voiceInfo.holdDuration").gte(holdDurationMin));
        }
        if (!Strings.isNullOrEmpty(holdDurationMax)) {
            boolQuery.must(QueryBuilders.rangeQuery("voiceInfo.holdDuration").lte(holdDurationMax));
        }
        if (!Strings.isNullOrEmpty(proStatus)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.proStatus", proStatus));
        }
        if (!Strings.isNullOrEmpty(sysTagFlags)) {
            PubMethod.formatSysTagFlags(boolQuery, Arrays.asList(sysTagFlags.split(",")));
        }
        if (!Strings.isNullOrEmpty(appealFlags)) {
            PubMethod.formatAppealFlags(boolQuery, Arrays.asList(appealFlags.split(",")));
        }
        //打标方
        if (Strings.isNullOrEmpty(telTagIds) && Strings.isNullOrEmpty(sysTagIds) && !Strings.isNullOrEmpty(tagUse) ) {
            BoolQueryBuilder builder = new BoolQueryBuilder();
            for (String tasUserO : tagUse.split(",")) {
                //总打标量(allTag)  系统打标量(sysTag)  人工打标量(addTag)  人工纠正量(corTag)
                if ("addTag".equals(tasUserO)) {
                    builder.should(
                            QueryBuilders.nestedQuery(
                                    "callTags",
                                    QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_ZJ),
                                    ScoreMode.None
                            )
                    );
                } else if ("sysTag".equals(tasUserO)) {
                    builder.should(
                            QueryBuilders.nestedQuery(
                                    "callTags",
                                    QueryBuilders.boolQuery()
                                            .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_SYS))
                                            .must(QueryBuilders.matchQuery("callTags.proValue", BaseEntity.PROVALUE_YES)),
                                    ScoreMode.None
                            )
                    );
                } else {
                    builder.should(
                            QueryBuilders.nestedQuery(
                                    "callTags",
                                    QueryBuilders.matchQuery("callTags.proValue", BaseEntity.PROVALUE_NO),
                                    ScoreMode.None
                            )
                    );
                }
            }
            boolQuery.must(builder);
        }
        //没有[系统打标量(sysTag)  人工打标量(addTag)  人工纠正量(corTag)]的概念
        if (!Strings.isNullOrEmpty(telTagIds) && !Strings.isNullOrEmpty(tagUse)) {
            boolQuery.must(QueryBuilders.matchQuery("callTags.proType", 9999));
        }
        //话务小结
        if (Strings.isNullOrEmpty(tagUse) && !Strings.isNullOrEmpty(telTagIds)) {
            BoolQueryBuilder shouldOrMustQ = new BoolQueryBuilder();
            for (String tagName : telTagIds.split(",")) {
                NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery(
                        "callTags",
                        QueryBuilders.boolQuery()
                                .must(QueryBuilders.prefixQuery("callTags.tagName", tagName))
                                .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_ZX)),
                        ScoreMode.None
                );
                if ("0".equals(telOperator)) {
                    shouldOrMustQ.should(nestedQueryBuilder);
                } else {
                    shouldOrMustQ.must(nestedQueryBuilder);
                }
            }
            boolQuery.must(shouldOrMustQ);
        }
        //系统标签
        if (!Strings.isNullOrEmpty(sysTagIds) && Strings.isNullOrEmpty(tagUse)) {
            BoolQueryBuilder shouldOrMustQ = new BoolQueryBuilder();
            for (String tagName : sysTagIds.split(",")) {
                BoolQueryBuilder proQ = new BoolQueryBuilder();
                proQ.should(
                        QueryBuilders.nestedQuery(
                                "callTags",
                                QueryBuilders.boolQuery()
                                        .must(QueryBuilders.wildcardQuery("callTags.tagName", tagName + "*"))
                                        .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_SYS))
                                        .must(QueryBuilders.matchQuery("callTags.proValue", BaseEntity.PROVALUE_YES)),
                                ScoreMode.None)
                ).should(
                        QueryBuilders.nestedQuery(
                                "callTags",
                                QueryBuilders.boolQuery()
                                        .must(QueryBuilders.wildcardQuery("callTags.tagName", tagName + "*"))
                                        .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_ZJ))
                                        .must(QueryBuilders.matchQuery("callTags.proValue", BaseEntity.PROVALUE_YES)),
                                ScoreMode.None)
                );
                if ("0".equals(sysOperator)) {
                    shouldOrMustQ.should(proQ);
                } else {
                    shouldOrMustQ.must(proQ);
                }
            }
            boolQuery.must(shouldOrMustQ);
        }
        if (!Strings.isNullOrEmpty(sysTagIds) && !Strings.isNullOrEmpty(tagUse) ) {
            BoolQueryBuilder shouldOrMustQ = new BoolQueryBuilder();
            for (String tagName : sysTagIds.split(",")) {
                BoolQueryBuilder builder = new BoolQueryBuilder();
                for (String tasUserO : tagUse.split(",")) {
                    //总打标量(allTag)  系统打标量(sysTag)  人工打标量(addTag)  人工纠正量(corTag)
                    if ("addTag".equals(tasUserO)) {
                        builder.should(
                                QueryBuilders.nestedQuery(
                                        "callTags",
                                        QueryBuilders.boolQuery()
                                                .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_ZJ))
                                                .must(QueryBuilders.prefixQuery("callTags.tagName", tagName)),
                                        ScoreMode.None
                                )
                        );
                    } else if ("sysTag".equals(tasUserO)) {
                        builder.should(
                                QueryBuilders.nestedQuery(
                                        "callTags",
                                        QueryBuilders.boolQuery()
                                                .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_SYS))
                                                .must(QueryBuilders.matchQuery("callTags.proValue", BaseEntity.PROVALUE_YES))
                                                .must(QueryBuilders.prefixQuery("callTags.tagName", tagName)),
                                        ScoreMode.None
                                )
                        );
                    } else {
                        builder.should(
                                QueryBuilders.nestedQuery(
                                        "callTags",
                                        QueryBuilders.boolQuery()
                                                .must(QueryBuilders.matchQuery("callTags.proValue", BaseEntity.PROVALUE_NO))
                                                .must(QueryBuilders.prefixQuery("callTags.tagName", tagName)),
                                        ScoreMode.None
                                )
                        );
                    }
                }
                if ("0".equals(sysOperator)) {
                    shouldOrMustQ.should(builder);
                } else {
                    shouldOrMustQ.must(builder);
                }
            }
            boolQuery.must(shouldOrMustQ);
        }
        //只查询话务小结
        if (!Strings.isNullOrEmpty(telTagAll)) {
            boolQuery.must(
                    QueryBuilders.nestedQuery(
                            "callTags",
                            QueryBuilders.boolQuery()
                                    .must(QueryBuilders.existsQuery("callTags.tagId"))
                                    .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_ZX)),
                            ScoreMode.None
                    )
            );
        } else if (!Strings.isNullOrEmpty(sysTagAll)) {
            boolQuery.must(
                    QueryBuilders.boolQuery().should(
                            QueryBuilders.nestedQuery(
                                    "callTags",
                                    QueryBuilders.boolQuery()
                                            .must(QueryBuilders.existsQuery("callTags.tagId"))
                                            .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_ZJ)),
                                    ScoreMode.None
                            )
                    ).should(
                            QueryBuilders.nestedQuery(
                                    "callTags",
                                    QueryBuilders.boolQuery()
                                            .must(QueryBuilders.existsQuery("callTags.tagId"))
                                            .must(QueryBuilders.matchQuery("callTags.proType", BaseEntity.PROTYPE_SYS)),
                                    ScoreMode.None
                            )
                    )
            );
        }
        if (!Strings.isNullOrEmpty(scenes)) {
            BoolQueryBuilder sceneQ = new BoolQueryBuilder();
            for (String scene : scenes.split(",")) {
                sceneQ.should(QueryBuilders.wildcardQuery("appeals.scene", scene + "*"));
            }
            boolQuery.must(
                    QueryBuilders.nestedQuery(
                            "appeals",
                            sceneQ,
                            ScoreMode.None
                    )
            );
        }
        return boolQuery;
    }

    @Override
    public HtmlResult searchData(String logTxt, Map<String, String[]> params, HttpServletRequest request) throws InvocationTargetException, IllegalAccessException {
        logger.info(logTxt);
        String pageNum = params.get("pageNum")[0];//起始页
        String pageSize = params.get("pageSize")[0];//每页条数
        String sortName = params.get("sortName")[0];//录音流水
        String sortOrder = params.get("sortOrder")[0];//录音流水
        BoolQueryBuilder boolQuery = getQuery(logTxt, params, request);
        String[] includes = new String[]
                {
                        "serialNumber",
                        "voiceInfo"
                };
        List<String> docList = SystemStatic.crud.queryMapQBuilderRetRuleAndWork(
                SystemStatic.AUDIO_ES_INDEX,
                SystemStatic.AUDIO_ES_TYPE,
                Integer.parseInt(pageNum),
                Integer.parseInt(pageSize),
                boolQuery,
                SystemStatic.crud.formatCloumn(sortName, SystemStatic.AUDIO_ES_INDEX),
                sortOrder,
                includes
        );
        logger.info(logTxt + "获取数据条数为：" + docList.size());
        return HtmlResult.success(
                esUtil.formatModel(docList),
                SystemStatic.crud.queryQBuilderAllByMes(SystemStatic.AUDIO_ES_INDEX, SystemStatic.AUDIO_ES_TYPE, boolQuery)
        );
    }

    public void exportMyAss(String logTxt, HttpServletRequest request, HttpServletResponse response, BoolQueryBuilder boolQuery, ESUtil esUtil) throws IOException, InvocationTargetException, IllegalAccessException {
        logger.info(logTxt);
        String sortName = request.getParameter("sortName");//录音流水
        String sortOrder = request.getParameter("sortOrder");//录音流水
        List<VoiceInfoDto> voiceInfos = new ArrayList<>();
        //总条数
        Integer sum = SystemStatic.crud.queryQBuilderAllByMes(SystemStatic.AUDIO_ES_INDEX, SystemStatic.AUDIO_ES_TYPE, boolQuery);
        //单词查询条数
        int excleMax = ConfigHelper.getInt("export.data.sheet.max.number", 1000);
        List<Integer> pageTout = TaskUtil.formatSum(sum, excleMax);//todo最后一个数字需要特殊处理:6022
        String[] includes = new String[]
                {
                        "serialNumber",
                        "voiceInfo",
                        "callTags"
                };
        for (Integer aPageTout : pageTout) {
            List<String> docs = SystemStatic.crud.queryMapQBuilderRetRuleAndWork(
                    SystemStatic.AUDIO_ES_INDEX,
                    SystemStatic.AUDIO_ES_TYPE,
                    aPageTout,
                    excleMax,
                    boolQuery,
                    SystemStatic.crud.formatCloumn(sortName, SystemStatic.AUDIO_ES_INDEX),
                    sortOrder,
                    includes
            );
            if (docs.isEmpty()) continue;
            voiceInfos.addAll(esUtil.formatModel(docs));
        }
        logger.info(logTxt + "获取数据条数为：" + voiceInfos.size());
        for (VoiceInfoDto dto : voiceInfos) {
            if (dto.getCallTags() == null || dto.getCallTags().isEmpty()) {
                dto.setBusTags("");
                dto.setSysTags("");
                continue;
            }
            StringBuilder busTags = new StringBuilder();//话务小结
            StringBuilder sysTags = new StringBuilder();//系统标签
            for (BusinessTags tag : dto.getCallTags()) {
                if (tag.getProType() == BaseEntity.PROTYPE_ZX) {//标签分类 0坐席[话务小结]
                    busTags.append(tag.getTagName()).append("\r\n");
                } else {
                    if (tag.getProValue() == BaseEntity.PROVALUE_YES) {//系统标签，正确的追加
                        sysTags.append(tag.getTagName()).append("\r\n");
                    }
                }
            }
            dto.setBusTags(busTags.toString());
            dto.setSysTags(sysTags.toString());
        }
        //设置标题和列名称
        String[] header = {"编号", "省份",  "呼叫类型", "录音流水", "坐席班组", "坐席工号",  "坐席姓名", "客户号码", "受理号码", "通话时长(秒)", "通话开始时间",
                "通话结束时间", "语音入库时间", "挂机方", "是否重复来电", "满意度", "客户归属地", "客户星级", "重要客户"};
        List<String> headerList = Arrays.asList(header);
        List<String> headers = new ArrayList<>(headerList);
        String methodType = request.getParameter("methodType");//请求来源  标签统计跳转(tagCount)  当页查询(search)
        if ("tagCount".equals(methodType)) {
            headers.add("话务小结");
            headers.add("系统标签");
        }
        //生成excel
        HSSFWorkbook workbook = new HSSFWorkbook();//创建一个xls文档对象
        HSSFSheet sheet = workbook.createSheet();//创建一个工作薄对象
        String title = "话单信息列表";
        XlsUtil.setTableTitleHeader(workbook, sheet, headers, title);
        //获取表文样式
        HSSFCellStyle tableStyle = XlsUtil.getTableStyle(workbook);
        HSSFRow row2;
        HSSFCell cell2;
        for (int j = 0; j < voiceInfos.size(); j++) {
            VoiceInfoDto voiceInfo = voiceInfos.get(j);
            row2 = sheet.createRow(3 + j);
            for (int i = 0; i < headers.size(); i++) {
                cell2 = row2.createCell(i);
                cell2.setCellStyle(tableStyle);
                switch (i) {
                    case 0:
                        cell2.setCellValue(new HSSFRichTextString((j + 1) + ""));
                        break;
                    case 1:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getProvince()));
                        break;
                    case 2:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getCallDirection() == 0 ? "呼入" : "呼出"));
                        break;
                    case 3:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getSerialNumber()));
                        break;
                    case 4:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getSeatGroup()));
                        break;
                    case 5:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getSeatId()));
                        break;
                    case 6:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getSeatName()));
                        break;
                    case 7:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getCustomerNum()));
                        break;
                    case 8:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getProPhoneNum()));
                        break;
                    case 9:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getHoldDuration() + ""));
                        break;
                    case 10:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getCallStartTime()));
                        break;
                    case 11:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getCallEndTime()));
                        break;
                    case 12:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getInputTime()));
                        break;
                    case 13:
                        cell2.setCellValue(new HSSFRichTextString(esUtil.changeOnHook(voiceInfo.getOnHook())));
                        break;
                    case 14:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getReCallFlag() == 0 ? "否" : "是"));
                        break;
                    case 15:
                        cell2.setCellValue(new HSSFRichTextString(esUtil.changeSatisfaction(voiceInfo.getSatisfaction())));
                        break;
                    case 16:
                        Map<String,Object> map =  SystemStatic.PROVINCE_CITY_MAP;
                        Map<String, String> citys = (Map<String, String>) map.get(voiceInfo.getProvinceCode());
                        String city = citys.get(voiceInfo.getCustomerloc());
                        cell2.setCellValue(new HSSFRichTextString(Strings.isNullOrEmpty(city) ? voiceInfo.getCustomerloc() : city));
                        break;
                    case 17:
                        cell2.setCellValue(new HSSFRichTextString(esUtil.changeCustomerLevel(voiceInfo.getCustomerLevel())));
                        break;
                    case 18:
                        String customerSign = "";
                        if (!Strings.isNullOrEmpty(voiceInfo.getCustomerSign())) {
                            customerSign = voiceInfo.getCustomerSign().equals("0") ? "否" : "是";
                        }
                        cell2.setCellValue(new HSSFRichTextString(customerSign));
                        break;
                    case 19:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getBusTags()));
                        break;
                    case 20:
                        cell2.setCellValue(new HSSFRichTextString(voiceInfo.getSysTags()));
                        break;
                }
            }
        }
        for (int i = 0; i < header.length; i++) {
            sheet.autoSizeColumn((short) i, true);//自动调整列宽
        }
        String fileName = title + "_" + DateFormatUtil.getNowTime() + ".xls";
        // 清空response
        response.reset();
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));  //转码之后下载的文件名不会出现中文乱码
        workbook.write(response.getOutputStream());
    }
}
